#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
#include <time.h>
#include "tickets.h"
#include "../server/dbHandler/dbHandler.h"
#include "../scanADT/strlib.h"
#include "../scanADT/random.h"
#include "../scanADT/gcalloc.h"
#include "../md5/global.h"
#include "../md5/md5.h"
#include "../clsv/clsv.h"
#include "../clsv/aux.h"
#include "../error/error.h"

int	
GetTicketParameters(char * database, char * md5, ticketP * tickp)
{
	resultT rta;
	char string[MAX_QSTRING];	
	int err;
	
	if (!dbfileExists(database))
		return NOT_OK;
	/* form the query string */
	sprintf(string, "SELECT id, filename, deliver, enable, expire, retries"
					" FROM tickets WHERE id LIKE '%s'", md5);
	/*query the database */
	err = query(database, string, &rta);

	if (err)
	{
		fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":"SQL error: "
				, rta.zErrMsg);
		return NOT_OK;
	}
	
	if (rta.nrow)
	{
		/*copy the ticket's parameters to the response */
		strcpy(tickp->id, rta.result[6]);
		tickp->dtime = atoi(rta.result[8]);
		tickp->etime = atoi(rta.result[9]);
		tickp->ftime = atoi(rta.result[10]);;
		tickp->retries = atoi(rta.result[11]);
	
		freeR(rta);
		return OK;
	}
	else
	{
		freeR(rta);
		return NOT_OK;
	}
}

int
TicketsLeft(char * database, int login)
{
	resultT rta, rta2;
	char string[MAX_QSTRING];
	int level;
	int err;

	if (!dbfileExists(database))
		return NOT_OK;
	
	/* form the query string */
	sprintf(string, "SELECT nivel from usuario where codigo = %d ;", login);
	
	/*query the database to see if the user exists and obtain his level*/
	err = query(database, string, &rta);
	
	if (err)
	{
		fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":"SQL error: ", 
				rta.zErrMsg);
		return -1;
	}
	
	if( rta.nrow )
	{
		int used;
		level = atoi(rta.result[1]);
		
		/* form the query string */
		sprintf(string, "SELECT used from dailytickets where code = %d"
				" and date = current_date;", login);
		
		/*query the database */
		err= query(database, string, &rta2);
	
		if( err ) 
		{
			fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":
					"SQL error: ", rta.zErrMsg);
			return -1;
		}
		
		if(rta2.nrow)
		{
			used = atoi(rta2.result[1]);
			freeR(rta);
			freeR(rta2);
			if(used < level)
			{
				return level-used;
			}
			else
				return 0;
		}
		else
		{
			freeR(rta2);
			/* if the user didn't request any tickets for the day*/
			/* form the query string */			
			sprintf(string, "INSERT INTO dailytickets values"
				" (%d, current_date, 0);", login);
			/*query the database */
			err= query(database, string, &rta2);
			
			if( err )
			{
				fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":
					"SQL error: ", rta.zErrMsg);
				return -1;
			}
			freeR(rta);
			freeR(rta2);
			return level - 1;
		}
	}
	else
	{
		freeR(rta);
		return 0;
	}	
}

int
IncTickets(char * database, int login)
{
	resultT rta;
	char string[MAX_QSTRING];
	int err, used;
	
	if (!dbfileExists(database))
		return NOT_OK;
	/*for query string */
	sprintf(string, "SELECT used FROM dailytickets WHERE code = %d"
			" and date = current_date;", login);
	
	/*query the database to see if user requested any tickets for the day*/ 
	err = query(database, string, &rta);
	
	if (err)
	{
		fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":"SQL error: "
				, rta.zErrMsg);
		return NOT_OK;
	}
	
	if (rta.nrow)
	{
		freeR(rta);
		used = atoi(rta.result[1]);
		/*query the database to increase the number of tickets requested for
		 * the day*/
		sprintf(string, "update dailytickets set used = %d where code = %d"
					" and date = current_date;", used + 1, login);
		
		err = query(database, string, &rta);

		if (err)
		{
			fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":
					"SQL error: ", rta.zErrMsg);
			return NOT_OK;
		}
		freeR(rta);
		
		return OK;
	}
	else
	{
		freeR(rta);
		return NOT_OK;
	}
}
		
		
int
RemoveTicket(char * database, ticketT md5)
{
	resultT rta;
	char string[MAX_QSTRING];	
	int err;
	
	if (!dbfileExists(database))
		return NOT_OK;
	/*build query string*/
	sprintf(string, "update tickets set removed = 1 where id like '%s';", md5);

	/*query the database */
	err = query(database, string, &rta);
	if (err)
	{
		fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":"SQL error: "
				, rta.zErrMsg);
		return NOT_OK;
	}

	freeR(rta);
	return OK;
}

int
IncreaseRetries(char * database, ticketT md5,ticketP * tickp)
{
	resultT rta;
	char string[MAX_QSTRING];	
	int err;
	
	if (!dbfileExists(database))
		return NOT_OK;
	/*build query string*/
	sprintf(string, "UPDATE tickets SET retries = %d WHERE id LIKE '%s';", 
			tickp->retries + 1, md5);
	/*query the database*/
	err = query(database, string, &rta);
	
	if (err)
	{
		fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":"SQL error: "
				, rta.zErrMsg);
		return NOT_OK;
	}
	
	freeR(rta);
	return OK;
}

/*creates the md5 that is ticket's id*/
char *
createId(char * filename, int pid, int dtime)
{
	char * id, * md5;
	
	if((id = malloc(MAX_FILEL+MAX_INT_LEN+MAX_INT_LEN+1)) == NULL)
		return NULL;
	/* build the string for the ticket id*/
	sprintf(id, "%s%d%d", filename, pid, dtime);

	if((md5 = malloc(MD5_SIZE+1)) == NULL)
		return NULL;
	
	/* create the md5 from the generated string */
	MDString(id, md5);
	md5[MD5_SIZE] = '\0';
	
	free(id);	
	return md5;
}
		

short
TicketExists(char * database, char * id, char * ip)
{
	resultT rta;
	char string[MAX_QSTRING];
	int err;
	
	if (!dbfileExists(database))
		return FALSE;
	
	/* build query string */
	sprintf(string, "SELECT removed FROM tickets WHERE id LIKE '%s' and ip"
					" LIKE '%s';", id, ip);	
		
	err = query(database, string, &rta);
	
	if (err)
	{
		fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":"SQL error: ", 
				rta.zErrMsg);
		return FALSE;
	}

	if (rta.nrow)
	{
		/*check if the ticket was removed */
		if (atoi(rta.result[1]) == 1)
		{
			freeR(rta);
			return FALSE;
		}
		freeR(rta);
		return TRUE;
	}
	else
	{
		freeR(rta);
		return FALSE;
	}
}


int
CreateTicket(char * database, char * filename, int pid, ticketP * tickp,
			 char * ip)
{
	resultT rta;
	char string[MAX_QSTRING];
	char * id;	
	int err;
	int removed = 0;
	
	if (!dbfileExists(database))
		return NOT_OK;
	
	/* set delivery time as current time in seconds*/
	tickp->dtime = time(NULL);
	
	if((id = createId(filename, pid, tickp->dtime)) == NULL)
		return NOT_OK;
	strcpy(tickp->id, id);
	
	/*generate random for enable time and expiration time of the ticket*/
	rand();
	tickp->etime = RandomInteger(tickp->dtime + 1, tickp->dtime + 600);
	tickp->ftime = RandomInteger(tickp->etime +100, tickp->etime + 600);
	tickp->retries = 0;	

	/*build query string */
	sprintf(string,
		"INSERT INTO tickets values ('%s', '%s', %d, %d, %d, %d, %d, '%s');", 
			id, filename, tickp->dtime, tickp->etime, tickp->ftime, 
			tickp->retries, removed, ip);
	
	/*query the database */
	err = query(database, string, &rta);
			
	if (err)
	{
		fprintf(stderr, "%s%s\n", err==1?"Can't open database: ":"SQL error: "
				, rta.zErrMsg);
		return NOT_OK;
	}
	else
	{
		freeR(rta);
		return OK;
	}
}


	
